﻿using System.Collections.Generic;
using EP.Base.BaseService.Manager.Business.QzJob;
using EP.Base.BaseService.Manager.Config;
using EP.Base.BaseService.Manager.Config.Constant;
using EP.Base.BaseService.Manager.Interface.Business;
using EP.Base.BaseService.Manager.Interface.Common;
using EP.Base.BaseService.Manager.Interface.Data;
using EP.Base.BaseService.Manager.Model.Entity;
using Quartz;
using Quartz.Impl;

namespace EP.Base.BaseService.Manager.Business.Scheduler
{
    /// <summary>
    /// 每个任务一个job，每个job独立设置计划
    /// </summary>
    public class EsServiceSingleSchedulerAutoMonitor:IAutoMonitorService
    {
        private readonly ILog _log;
        private readonly IEsMaintainTask _esMaintainTask;
        private readonly IServiceSimplifyLog _serviceSimplifyLog;
        private readonly IEsTaskConfigs _esTaskConfigs;
        //从工厂中获取一个调度器实例化
        IScheduler _scheduler;
        //private readonly string _cron = EsMaintainTaskConfig.TaskSchedule;
        public EsServiceSingleSchedulerAutoMonitor(ILog log, IEsMaintainTask esMaintainTask, IServiceSimplifyLog serviceSimplifyLog, IEsTaskConfigs esTaskConfigs)
        {
            _log = log;
            _esMaintainTask = esMaintainTask;
            _serviceSimplifyLog = serviceSimplifyLog;
            _esTaskConfigs = esTaskConfigs;
        }

        public void Start()
        {
            _serviceSimplifyLog.ExecSl("创建定时任务",()=>
            {
                var currentTasks=new List<EsTaskConfig>();
                _scheduler = StdSchedulerFactory.GetDefaultScheduler();
                //开启调度器
                _scheduler.Start();
                var tasks = _esTaskConfigs.GetAll();
                if (tasks != null)
                {
                    currentTasks.AddRange(tasks);

                    _log.DebugFormat("得到任务count={0}",tasks.Count);
                    foreach (var esTaskConfig in tasks)
                    {
                        AddTask(esTaskConfig);
                    }

                    #region 创建监控job
                    //创建一个作业
                    IJobDetail srcInitJob = JobBuilder.Create<EsTaskConfigMonitorQzJob>()
                        .WithIdentity("EsTaskJob_Monitor", EsTaskQzConfig.EsTaskJobGroup)
                        .Build();
                    srcInitJob.JobDataMap.Add("IEsMaintainTask", _esMaintainTask);
                    srcInitJob.JobDataMap.Add("IServiceSimplifyLog", _serviceSimplifyLog);
                    srcInitJob.JobDataMap.Add("CurrentTasks", currentTasks);
                    srcInitJob.JobDataMap.Add("IEsTaskConfigs", _esTaskConfigs);
                    srcInitJob.JobDataMap.Add("ILog",_log);
                    //定义触发器
                    ITrigger trigger = TriggerBuilder.Create()
                        .WithIdentity("EsTaskJob_Monitor", EsTaskQzConfig.EsTaskTriggerGroup)
                        .StartNow() //现在开始
                        .WithCronSchedule(EsMaintainTaskConfig.TaskConfigChangeMonitorCron) //cron表达式
                        .Build();
                    //把作业，触发器加入调度器。
                    _scheduler.ScheduleJob(srcInitJob, trigger);
                    #endregion
                }

            });
           
        }

        private void AddTask(EsTaskConfig esTaskConfig)
        {
            _log.DebugFormat("任务esTaskConfigId={0}创建定时任务。", esTaskConfig.Id);
            //创建一个作业
            IJobDetail srcInitJob = JobBuilder.Create<EsMaintainSingleTaskQzJob>()
                .WithIdentity(EsTaskQzConfig.EsTaskJobPre + esTaskConfig.Id, EsTaskQzConfig.EsTaskJobGroup)
                .Build();
            srcInitJob.JobDataMap.Add("IEsMaintainTask", _esMaintainTask);
            srcInitJob.JobDataMap.Add("IServiceSimplifyLog", _serviceSimplifyLog);
            srcInitJob.JobDataMap.Add("EsTaskConfigId", esTaskConfig.Id);
            //定义触发器
            ITrigger trigger = TriggerBuilder.Create()
                .WithIdentity(EsTaskQzConfig.EsTaskTriggerPre + esTaskConfig.Id, EsTaskQzConfig.EsTaskTriggerGroup)
                .StartNow() //现在开始
                .WithCronSchedule(esTaskConfig.Cron) //cron表达式
                .Build();

            //把作业，触发器加入调度器。
            _scheduler.ScheduleJob(srcInitJob, trigger);
        }

        public void WriteDebugMsg(string msg)
        {
            _log.Debug(msg);
        }

        public void WriteErrorMsg(string msg)
        {
            _log.Error(msg);
        }

        public void Stop()
        {
            _serviceSimplifyLog.ExecSl("停止定时任务", () =>
            {
                if (_scheduler != null)
                    _scheduler.Shutdown();
            });
        }

        public void Dispose()
        {
           //
        }
    }
}
